using Circus.CodeEditor;
using Circus.Syntax;
using Circus.Syntax.CodeCompletion;
using Circus.Syntax.Lexer;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
namespace Circus.CodeEditor.CodeCompletion
{
	[DesignTimeVisible(false), ToolboxItem(false)]
	public class CodeCompletionHint : CodeCompletionWindow,  ICodeCompletionWindow
	{
		private Point curPos;
		private bool autoHide;
		private Timer hideTimer;
	
		protected override CreateParams CreateParams
		{
			get
			{
				OSUtils.InitCommonControls();
				CreateParams createParams = base.CreateParams;
				createParams.Parent = IntPtr.Zero;
				createParams.ClassName = "tooltips_class32";
				createParams.Style |= 1;
				createParams.ExStyle = 0;
				return createParams;
			}
		}
		protected CompletionHint Hint
		{
			get
			{
				return (CompletionHint)this.PopupControl;
			}
		}
		protected Timer HideTimer
		{
			get
			{
				if (this.hideTimer == null)
				{
					this.hideTimer = new Timer();
					this.hideTimer.Enabled = false;
					this.hideTimer.Interval = EditConsts.DefaultHideHintDelay;
					this.hideTimer.Tick += new EventHandler(this.OnHideHint);
				}
				return this.hideTimer;
			}
		}
		public virtual bool AutoHide
		{
			get
			{
				return this.autoHide;
			}
			set
			{
				if (this.autoHide != value)
				{
					this.autoHide = value;
					this.OnAutoHideChanged();
				}
			}
		}
		public virtual int AutoHidePause
		{
			get
			{
				return (this.hideTimer != null) ? this.hideTimer.Interval : EditConsts.DefaultHideHintDelay;
			}
			set
			{
				if (this.HideTimer != null && this.HideTimer.Interval != value)
				{
					this.HideTimer.Interval = value;
					this.OnIntervalChanged();
				}
			}
		}
		public virtual bool DisableColorPaint
		{
			get
			{
				return this.Hint.SyntaxPaint.DisableColorPaint;
			}
			set
			{
				if (this.Hint != null && this.Hint.SyntaxPaint != null && this.Hint.SyntaxPaint.DisableColorPaint != value)
				{
					this.Hint.SyntaxPaint.DisableColorPaint = value;
					this.OnDisableColorPaintChanged();
				}
			}
		}
		public virtual bool DisableSyntaxPaint
		{
			get
			{
				return this.Hint.SyntaxPaint.DisableSyntaxPaint;
			}
			set
			{
				if (this.Hint != null && this.Hint.SyntaxPaint != null && this.Hint.SyntaxPaint.DisableSyntaxPaint != value)
				{
					this.Hint.SyntaxPaint.DisableSyntaxPaint = value;
					this.OnDisableSyntaxPaintChanged();
				}
			}
		}
		public virtual Circus.Syntax.Lexer.Lexer Lexer
		{
			get
			{
				return this.Hint.SyntaxPaint.Lexer;
			}
			set
			{
				if (this.Hint != null && this.Hint.SyntaxPaint != null && this.Hint.SyntaxPaint.Lexer != value)
				{
					this.Hint.SyntaxPaint.Lexer = value;
					this.OnLexerChanged();
				}
			}
		}
	 
		protected bool UpdateProviderContent(ICodeCompletionProvider pr1, ICodeCompletionProvider pr2)
		{
			bool flag = pr1 is ListMembers && pr2 is ListMembers;
			if (flag)
			{
				flag = (pr1.Count == pr2.Count);
				if (flag)
				{
					for (int i = 0; i < pr1.Count; i++)
					{
						ListMember listMember = (ListMember)pr1[i];
						ListMember listMember2 = (ListMember)pr2[i];
						flag = (listMember.Name == listMember2.Name && listMember.GetParamText(false) == listMember2.GetParamText(false));
						if (!flag)
						{
							break;
						}
					}
				}
			}
			if (flag)
			{
				for (int i = 0; i < pr1.Count; i++)
				{
					ListMember listMember = (ListMember)pr1[i];
					ListMember listMember2 = (ListMember)pr2[i];
					listMember.CurrentParamIndex = listMember2.CurrentParamIndex;
				}
			}
			return flag;
		}
		protected void PositionChanged()
		{
			CodeEditor syntaxEdit = base.GetSyntaxEdit();
			if (syntaxEdit != null && this.StartPos.X >= 0 && this.StartPos.Y >= 0 && !this.curPos.Equals(syntaxEdit.Position))
			{
				this.curPos = syntaxEdit.Position;
				if (this.Provider is ParameterInfo)
				{
					CodeCompletionArgs codeCompletionArgs = new CodeCompletionArgs();
					codeCompletionArgs.CompletionType = CodeCompletionType.ParameterInfo;
					codeCompletionArgs.NeedReparse = true;
					codeCompletionArgs.AllowAsync = false;
					codeCompletionArgs.Notify = false;
					codeCompletionArgs.Lexer = this.Lexer;
					syntaxEdit.CodeCompletion(codeCompletionArgs);
					if (!codeCompletionArgs.NeedShow)
					{
						codeCompletionArgs.Provider = null;
					}
					Point startPosition = codeCompletionArgs.StartPosition;
					if (this.StartPos.Equals(startPosition))
					{
						if (!this.UpdateProviderContent(this.Provider, codeCompletionArgs.Provider))
						{
							this.Provider = codeCompletionArgs.Provider;
						}
					}
					else
					{
						this.Provider = codeCompletionArgs.Provider;
						this.StartPos = startPosition;
						this.DisplayPos = startPosition;
						this.EndPos = codeCompletionArgs.EndPosition;
					}
				}
				if (this.Provider == null || this.Provider.Count == 0)
				{
					this.Close(false);
				}
				else
				{
					this.Hint.UpdateHint();
				}
			}
		}
		protected void DoUpdateSize(object sender, EventArgs e)
		{
			base.Size = this.Hint.HintSize;
		}
		protected override void DoShow(Point position)
		{
			base.DoShow(position);
			if (this.Provider != null && this.Provider.SelIndex >= 0)
			{
				this.Hint.SelectedIndex = this.Provider.SelIndex;
			}
			this.Hint.UpdateHint();
			base.Update();
			if (this.autoHide)
			{
				this.HideTimer.Enabled = true;
			}
		}
		protected override void DoHide()
		{
			base.DoHide();
			if (this.hideTimer != null)
			{
				this.hideTimer.Enabled = false;
			}
		}
		protected void OnHideHint(object sender, EventArgs e)
		{
			this.Close(false);
		}
		protected override void CheckPositionValid()
		{
		}
		protected override Control CreatePopupControl()
		{
			CompletionHint completionHint = new CompletionHint();
			completionHint.MouseWheel += new MouseEventHandler(this.DoMouseWheel);
			return completionHint;
		}
		protected override int GetSelectedIndex()
		{
			return this.Hint.SelectedIndex;
		}
		protected override void SetProvider(ICodeCompletionProvider provider)
		{
			this.Hint.Provider = provider;
		}
		protected override void OnStartPosChanged()
		{
			base.OnStartPosChanged();
			this.Hint.StartPos = this.StartPos;
		}
		protected virtual void Reposition()
		{
			if (this.DisplayPos.Y >= 0 && this.DisplayPos.X >= 0)
			{
				CodeEditor syntaxEdit = base.GetSyntaxEdit();
				Point p = syntaxEdit.TextToScreen(this.DisplayPos);
				p.Y = Math.Min(Math.Max(p.Y + syntaxEdit.Painter.FontHeight + EditConsts.DefaultHintOffsetY, syntaxEdit.ClientRect.Top), syntaxEdit.ClientRect.Bottom - base.Height);
				base.Top = syntaxEdit.PointToScreen(p).Y;
				this.DisplayPos = new Point(this.DisplayPos.X, this.DisplayPos.Y + 1);
			}
		}
		protected virtual void DoMouseWheel(object sender, MouseEventArgs e)
		{
			CodeEditor syntaxEdit = base.GetSyntaxEdit();
			if (syntaxEdit != null)
			{
			    syntaxEdit.handleMouseScroll(e.Delta);
			    this.Reposition();
			}
		}
		protected override bool ProcessKeyPreview(ref Message m)
		{
			bool result;
			if (this.OnProcessKeyPreview(ref m))
			{
				result = true;
			}
			else
			{
				if (m.Msg == 256 || m.Msg == 260)
				{
					Keys keys = (Keys)(m.WParam.ToInt32() & 65535);
					Keys keys2 = keys;
					if (keys2 != Keys.Return)
					{
						switch (keys2)
						{
						case Keys.Prior:
						case Keys.Next:
						case Keys.End:
						case Keys.Home:
							this.Close(false);
							break;
						case Keys.Up:
							if (this.Hint.NeedArrows)
							{
								this.Hint.ChangeSelection(false);
								result = true;
								return result;
							}
							this.Close(false);
							break;
						case Keys.Down:
							if (this.Hint.NeedArrows)
							{
								this.Hint.ChangeSelection(true);
								result = true;
								return result;
							}
							this.Close(false);
							break;
						}
					}
					else
					{
						if ((this.CompletionFlags & CodeCompletionFlags.AcceptOnEnter) != CodeCompletionFlags.None)
						{
							this.Close(true, '\r');
							result = true;
							return result;
						}
						this.Reposition();
					}
				}
				if (m.Msg == 258)
				{
					char value = (char)m.WParam.ToInt32();
					CodeEditor syntaxEdit = base.GetSyntaxEdit();
					if (syntaxEdit != null && syntaxEdit.Lexer is SyntaxParser && Array.IndexOf<char>(((SyntaxParser)syntaxEdit.Lexer).CodeCompletionStopChars, value) >= 0)
					{
						this.Close(false);
					}
				}
				bool flag = base.ProcessKeyPreview(ref m);
				this.PositionChanged();
				base.CheckPositionValid();
				result = flag;
			}
			return result;
		}
		public CodeCompletionHint(CodeEditor owner) : base(owner)
		{
			this.Sizeable = false;
			base.FormBorderStyle = FormBorderStyle.FixedToolWindow;
			this.BackColor = Consts.DefaultPopupBackColor;
			this.Font = new Font(EditConsts.DefaultCodeCompletionFont, EditConsts.DefaultCodeCompletionFontSize);
			this.curPos = new Point(0, 0);
			base.SetStyle(ControlStyles.UserPaint | ControlStyles.Opaque | ControlStyles.StandardClick | ControlStyles.StandardDoubleClick | ControlStyles.AllPaintingInWmPaint, true);
			CompletionHint expr_5B = this.Hint;
			expr_5B.UpdateSize = (EventHandler)Delegate.Combine(expr_5B.UpdateSize, new EventHandler(this.DoUpdateSize));
			this.Hint.MouseLeave += new EventHandler(this.CheckMouseLeave);
			this.CompletionFlags &= ~(CodeCompletionFlags.AcceptOnEnter | CodeCompletionFlags.AcceptOnDblClick | CodeCompletionFlags.AcceptOnDelimiter | CodeCompletionFlags.AcceptOnSpace);
		}
		public override void ResetContent()
		{
			this.Hint.ResetContent();
		}
		protected virtual void OnIntervalChanged()
		{
		}
		protected virtual void OnAutoHideChanged()
		{
			if (this.autoHide && base.Visible)
			{
				this.HideTimer.Enabled = true;
			}
		}
		public virtual void ResetAutoHide()
		{
			this.AutoHide = false;
		}
		public virtual void ResetAutoHidePause()
		{
			this.AutoHidePause = EditConsts.DefaultHideHintDelay;
		}
		protected virtual void OnDisableColorPaintChanged()
		{
		}
		protected virtual void OnDisableSyntaxPaintChanged()
		{
		}
		protected virtual void OnLexerChanged()
		{
		}
		protected virtual void OnBackColorChanged()
		{
		}
		public virtual void PaintSyntax(Painter painter, int startLine, int endLine, Point position, Rectangle rect, Point location, bool specialPaint)
		{
			this.Hint.SyntaxPaint.PaintSyntax(painter, startLine, endLine, position, rect, location, specialPaint);
		}
		public virtual void DrawLine(int index, Point position, Rectangle clipRect)
		{
			this.Hint.SyntaxPaint.DrawLine(index, position, clipRect);
		}
		public virtual void DrawLine(int index, string line, StringItemInfo[] colorData, Point position, Rectangle clipRect)
		{
			this.Hint.SyntaxPaint.DrawLine(index, line, colorData, position, clipRect);
		}
		public virtual int MeasureLine(int index, int pos, int len)
		{
			return this.Hint.SyntaxPaint.MeasureLine(index, pos, len);
		}
		public virtual int MeasureLine(int index, int pos, int len, int width, out int chars, bool exact)
		{
			return this.Hint.SyntaxPaint.MeasureLine(index, pos, len, width, out chars, exact);
		}
		public virtual int MeasureLine(string line, StringItemInfo[] colorData, int pos, int len)
		{
			return this.Hint.SyntaxPaint.MeasureLine(line, colorData, pos, len);
		}
		public virtual int MeasureLine(string line, StringItemInfo[] colorData, int pos, int len, int width, out int chars, bool exact)
		{
			return this.Hint.SyntaxPaint.MeasureLine(line, colorData, pos, len, width, out chars, exact);
		}
		public virtual Color GetFontColor(Color color, TextStyle textStyle)
		{
			return this.Hint.SyntaxPaint.GetFontColor(color, textStyle);
		}
		public virtual FontStyle GetFontStyle(FontStyle fontStyle, TextStyle textStyle)
		{
			return this.Hint.SyntaxPaint.GetFontStyle(fontStyle, textStyle);
		}
		public virtual LexStyle GetLexStyle(StringItemInfo style, ref TextStyle textStyle)
		{
			return this.Hint.SyntaxPaint.GetLexStyle(style, ref textStyle);
		}
		public virtual bool EqualStyles(StringItemInfo style1, StringItemInfo style2, bool useColors)
		{
			return this.Hint.SyntaxPaint.EqualStyles(style1, style2, useColors);
		}
	
		protected override void Dispose(bool disposing)
		{
			if (disposing)
			{
				if (this.hideTimer != null)
				{
					this.hideTimer.Dispose();
					this.hideTimer = null;
				}
				CompletionHint hint = this.Hint;
				if (hint != null)
				{
					hint.MouseWheel -= new MouseEventHandler(this.DoMouseWheel);
				}
			}
			base.Dispose(disposing);
		}
	}
}
